﻿using FreeSql;
using Infrastructure;
using SqlSugar;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Core
{
    /// <summary>
    /// 上料计划
    /// </summary>
    public static class LoadingPlanHelper
    {
        public static readonly object _lockPlan = new object();
        
        /// <summary>
        ///  
        /// </summary>
        /// <returns>存在则执行验证，为null代表不需要上料 </returns>
        public static CksLoadingPlan GetLoadingPlan(DbConnection conn)
        {

            lock (_lockPlan)
            {


                var plan = conn.Select<CksLoadingPlan>().Where(a => a.Status == 1).First();
                if (plan == null)
                {
                    plan = BuildNextPlan(conn);
                }
                if (plan.Id > 0)
                    return plan;
                else
                    return null;
            }

        }
        /// <summary>
        ///  生成下一个上料计划和计划明细
        /// </summary>
        /// <param name="lastPlan"></param>
        /// <returns></returns>
        private static CksLoadingPlan BuildNextPlan(DbConnection conn)
        {
            var lastPlan = conn.Select<CksLoadingPlan>().OrderByDescending(a => a.Id).First();
            CksLoadingPlan plan;
            //查询计划配置
            var ALlPartConfig = conn.Select<CksLoadingplanConfig>().ToList();
            var LastPlanDetails = new List<CksLoadingPlanDetails>();
            plan = new CksLoadingPlan();
            plan.Status = 1;
            plan.StartTime = DateTime.Now;
            plan.CreatedTime = DateTime.Now;

            if (lastPlan != null)
            {
                //查询上次计划明细
                LastPlanDetails = conn.Select<CksLoadingPlanDetails>()
                    .Where(a => a.PlanId == lastPlan.Id).ToList();
            }
            List<CksLoadingPlanDetails> newPlanDetails = new List<CksLoadingPlanDetails>();
            foreach (var partConfig in ALlPartConfig)
            {
                //查询指定周期类上料零件的子篮总数
                //partConfig.PeriodHour
                var time = DateTime.Now.AddMinutes(-1 * partConfig.PeriodHour * 60);
                var InCount = conn.Select<CksBasketcleaningRecord>()
                    .Where(a => a.InTime >= time && a.Type == partConfig.PartType)
                    .Count(); //进入的子篮数量

                var last = LastPlanDetails.Find(a => a.PartType == partConfig.PartType);
                int lastInCount = 0;
                if (last != null)
                    lastInCount = last.RealCount;
                lastInCount = lastInCount == 0 ? partConfig.SingleCount : lastInCount;
                // 2-  (3 - 2)   
                var needCount = partConfig.SingleCount - (lastInCount - partConfig.SingleCount);
                CksLoadingPlanDetails partPlan = null;
                if (needCount > 0)
                {
                    //需要零件
                    partPlan = new CksLoadingPlanDetails();
                    partPlan.PlanCount = needCount;
                    partPlan.Status = 1;
                    partPlan.Flag = 1;
                 
                }
                else if (needCount < 0)
                {
                    //不需要零件,但是上次投料太多，因此产生一条记录为立即完成的状态
                    partPlan = new CksLoadingPlanDetails();
                    partPlan.PlanCount = Math.Abs(needCount);
                    partPlan.Status = 10;
                    partPlan.Flag = 2;
                   
                }
                if (partPlan != null)
                {
                    partPlan.Line = partConfig.Line;
                    partPlan.PartType = partConfig.PartType;
                    partPlan.CreatedTime = DateTime.Now;
                    partPlan.Order = partConfig.Order;
                
                    newPlanDetails.Add(partPlan);
                }

            }
            if ( newPlanDetails.Count > 0)
            {
                plan.Id = conn.Insert(plan).ExecuteIdentity();
                newPlanDetails.ForEach(a => { a.PlanId = plan.Id; });
                conn.Insert(newPlanDetails).ExecuteAffrows();
            }

            return plan;
        }

        /// <summary>
        /// 获取下一个推荐上料的零件类型
        /// </summary>
        /// <returns></returns>
        public static int GetNextPartType()
        {
            return 0;
        }

    }
}
